package com.obj.commpont.common.aop;

import com.obj.commpont.common.annotation.ParamsToNull;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * TODO
 *
 * @author dell 2018/11/23 11:45
 */
@Slf4j
@Aspect
public class ParamsToNullAop {

    /**
     * 注解方法切入点
     **/
    @Pointcut("@annotation(ParamsToNull)")
    public void saveOrUpdatePointcut() {
        log.info("修改方法中指定的参数值为空aop");
    }

    @Around("saveOrUpdatePointcut()")
    public Object doBeforeRuning(ProceedingJoinPoint joinPoint) {
        try {
            return updateToNull(joinPoint);
        } catch (Throwable throwable) {
            log.error(throwable.getMessage());
            return null;
        }
    }

    public Object updateToNull(ProceedingJoinPoint joinPoint) throws Throwable {
        //获取类名
        String className = joinPoint.getTarget().getClass().getName();
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        //获取该方法
        Method targetMethod = methodSignature.getMethod();
        //方法名
        String methodName = targetMethod.getName();
        //获取方法中的注解
        ParamsToNull annotation = targetMethod.getAnnotation(ParamsToNull.class);
        String[] values = annotation.value();
        //方法中的参数
        Object[] params = joinPoint.getArgs();

        log.info("ParamsToNullAop切入类：{}方法：{}", className, methodName);

        if (annotation != null && values.length > 0) {
            if (methodName != null && params.length > 0) {
                //遍历所有的参数
                for (Object param : params) {
                    if (param != null) {
                        for (String item : values) {
                            //反射获取对象的属性值
                            Field field = ReflectionUtils.findField(param.getClass(), item);
                            if (field != null) {
                                //设置对象为空值
                                field.setAccessible(true);
                                field.set(param, null);
                            }
                        }
                    }
                }
            }
        }
        return joinPoint.proceed(params);
    }
}
